// VBlock.h
// This file defines class VBlock
#ifndef VBLOCK_H
#define VBLOCK_H

#include "crossbit/VInst.h"
#include "crossbit/VBlockBuilder.h"
#include <vector>
#include <iterator>
#include <iostream>
#include <iomanip>

namespace crossbit {

		// For the beginning, VBlock is just an wrap class for vector<VInst *>
		class VBlock {
				//								friend void VBlockBuilder::add(VInst *inst);
				//								friend VBlock* VBlockBuilder::wrapUp(XTMemAddr pc);

				public:
						typedef std::vector<VInst *>::iterator				vb_iterator;
						typedef std::vector<VInst *>::const_iterator			vb_const_iterator;
						typedef std::vector<VInst *>::reverse_iterator		vb_reverse_iterator;
						typedef std::vector<VInst *>::const_reverse_iterator	vb_const_reverse_iterator;

						VBlock(XTMemAddr enter_spc) 
								: vb_enter_spc(enter_spc) { vb_next_spc = 0;}

						~VBlock() { clear(); }

						void push_back(VInst * const inst) { vb_ilist.push_back(inst); }

						vb_iterator insert(vb_iterator it, VInst * const vinst) 
						{ return vb_ilist.insert(it, vinst); }

						vb_iterator erase(vb_iterator it) 
						{ return vb_ilist.erase(it); }

						XTUint32 size() const { return vb_ilist.size(); }

						bool empty() const { return vb_ilist.empty(); }

						void setVbIlist(XTInt32 index, VInst *inst)
						{
								if( index >= 0 && index <= vb_ilist.size() )
										vb_ilist[index] = inst;
								else
										return;
						}

						// instruction iterator methods
						vb_iterator		    		begin()			{ return vb_ilist.begin(); }
						vb_const_iterator			begin()	const	{ return vb_ilist.begin(); }
						vb_iterator		    		end()		    { return vb_ilist.end(); }
						vb_const_iterator			end()	const	{ return vb_ilist.end(); }
						vb_reverse_iterator			rbegin()		{ return vb_ilist.rbegin(); }
						vb_const_reverse_iterator	rbegin()const	{ return vb_ilist.rbegin(); }
						vb_reverse_iterator	    	rend()			{ return vb_ilist.rend(); }
						vb_const_reverse_iterator  	rend()	const	{ return vb_ilist.rend(); }

						void clear() 
						{
								for (vb_iterator it = vb_ilist.begin(); it != vb_ilist.end(); ++it)
										delete (*it);
								vb_ilist.clear();
						}

						XTMemAddr enterSPC()	const	{ return vb_enter_spc; }
						XTMemAddr nextSPC()	const	{ return vb_next_spc; }

						void setVbNextSpc( XTMemAddr spc )
						{
								vb_next_spc = spc;
								return;
						}

						void print(std::ostream &os) {
								vb_iterator I = begin(),
											E = end();

								for (int i = 0; I != E; ++I, ++i) {
										os << std::setw(3) << std::right << i << ": " << **I << std::endl;
								}
						}

				private:
						XTMemAddr vb_enter_spc;
						XTMemAddr vb_next_spc;
						std::vector<VInst *> vb_ilist;

						// forbid copy constructor
						VBlock(const VBlock &) {}

						// forbid copy assignment
						VBlock& operator=(const VBlock &) 
						{ return *this; }     
		};

}

#endif
